﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using FarseerPhysics.Factories;
using FarseerPhysics.Dynamics;

namespace Doodleberg
{
    class LineInputManager
    {
        private List<Line> current;
        private Line currentLine;
        private int editvert;

        public void update(GameTime gameTime)
        {
            MouseState mouseState = Mouse.GetState();

            if (Global.gameProperties.controlManager.getControl(ControlManager.DRAW))
            {
                if (currentLine == null)
                {
                    editvert = 1;
                    currentLine = new Line(
                        new Vector2(mouseState.X, mouseState.Y),
                        new Vector2(mouseState.X, mouseState.Y),
                        Global.def_restitution);
                    currentLine.deletable = true;
                    current = new List<Line>();
                    current.Add(currentLine);
                }
                else
                {
                    Vector2 newend = new Vector2(mouseState.X, mouseState.Y);
                    Vector2 currentend;
                    if (editvert == 1)
                        currentend = currentLine.getVert(1);
                    else
                        currentend = currentLine.getVert(2);

                    //Find length of current curve
                    int tempLen = 0;
                    foreach (Line tline in current)
                        tempLen += (int)tline.getLength();

                    //Make sure line stays within ink limit
                    bool overink = false;
                    if (Global.gameProperties.currentInk + tempLen >= Global.maxInk)
                        overink = true;

                    if (!overink)
                    {
                        currentLine.setVert(editvert, newend);

                        //Start a new segment every few px
                        if (currentLine.getLength() > Global.seglen &&
                            !Global.gameProperties.controlManager.getControl(ControlManager.STRAIGHTLINE))
                        {
                            currentLine = new Line(
                                new Vector2(mouseState.X, mouseState.Y),
                                new Vector2(mouseState.X, mouseState.Y),
                                Global.def_restitution);
                            currentLine.deletable = true;
                            current.Add(currentLine);
                        }

                        currentLine.setVert(editvert, newend);
                    }

                    //Switch editing vert to keep vert 1 on the left
                    if (currentLine.getVert(1).X > currentLine.getVert(2).X)
                    {
                        Vector2 temp = currentLine.getVert(1);
                        currentLine.setVert(1, currentLine.getVert(2));
                        currentLine.setVert(2, temp);
                        editvert = Global.vertswap(editvert);
                    }
                }
            }
            else
            {
                //Stop drawing line
                if (currentLine != null)
                {
                    //Find length of current curve
                    int tempLen = 0;
                    foreach (Line tline in current)
                        tempLen += (int)tline.getLength();

                    //Set the line up in Farseer
                    foreach (Line l in current)
                    {
                        Body temp = BodyFactory.CreateEdge(
                            Global.level.phyWorld,
                            l.getVert(1) / Global.farseer_conversion,
                            l.getVert(2) / Global.farseer_conversion);
                        temp.BodyType = BodyType.Static;
                        temp.Restitution = Global.def_restitution;
                        l.body = temp;
                    }

                    //Add it to the ink count
                    Global.gameProperties.currentInk += tempLen;

                    Global.level.lines.Add(current);
                    current = null;
                    currentLine = null;
                }
            }


            //Delete lines
            if (Global.gameProperties.controlManager.getControl(ControlManager.DELETE))
            {
                List<Line> removeMe = null;
                foreach (List<Line> tArray in Global.level.lines)
                {
                    foreach (Line tActLine in tArray)
                    {
                        if (tActLine.getDistanceTo(mouseState.X, mouseState.Y) < Global.lineDeleteThreshold
                            && tActLine.deletable)
                            removeMe = tArray;
                    }
                }
                if (removeMe != null)
                {
                    //Find length of removed curve
                    int tempLen = 0;
                    foreach (Line tline in removeMe)
                        tempLen += (int)tline.getLength();

                    //Refund ink
                    Global.gameProperties.currentInk -= tempLen;

                    //Destroy body
                    foreach (Line tline in removeMe)
                        Global.level.phyWorld.RemoveBody(tline.body);

                    //Remove
                    Global.level.lines.Remove(removeMe);
                }
            }
        }


        public void draw(SpriteBatch spriteBatch)
        {
            //Current curve
            if (current != null)
            {
                foreach (Line tline in current)
                {
                    Texture2D usetex = Global.level.tex_linedrawn;
                    Vector2 temp;
                    if (tline.getVert(1).X < tline.getVert(2).X)
                        temp = tline.getVert(1);
                    else
                        temp = tline.getVert(2);

                    spriteBatch.Draw(
                        usetex,
                        temp,
                        null,
                        Color.White,
                        tline.getAngle(),
                        new Vector2(0.0f, usetex.Height / 2),
                        new Vector2(tline.getLength() / 100.0f, 1.0f),
                        SpriteEffects.None,
                        0.7f);
                }
            }
        }
    }
}
